package cn.easyutil.easyproject.easySpringboot.handler;

import cn.easyutil.easyproject.easySpringboot.bean.common.Page;
import cn.easyutil.easyproject.easySpringboot.bean.common.ResponseBody;
import cn.easyutil.easyproject.easySpringboot.context.Context;
import cn.easyutil.easyproject.easySpringboot.util.RequestPool;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import com.example.easyJavaUtil.JsonUtil;
import com.example.easyJavaUtil.LoggerUtil;
import com.example.easyJavaUtil.ObjectUtil;
import com.example.easyJavaUtil.StringUtil;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Collection;

/**
 * body体的请求返回的包装
 * @author spc
 *
 */
@RestControllerAdvice
public class ResponseHandler implements ResponseBodyAdvice {
	@Value("${enableAuth}")
	private boolean enableAuth;

    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
                                  Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
    	HttpServletResponse rs = ((ServletServerHttpResponse) response).getServletResponse();
    	Class<?> type = returnType.getMethod().getReturnType();
    	rs.setHeader("UserCookie", "SESSION="+ RequestPool.getSession().getId()+";path=/;HttpOnly");
        if (ServletRequestAuthorition.useResponse.get() == null || !ServletRequestAuthorition.useResponse.get()) {
        	ServletRequestAuthorition.useResponse.remove();
            return body;
        }
        String userId = "";
        if(RequestPool.getUserNotException() != null){
        	userId = RequestPool.getUserId().toString();
        }
        //请求的接口
        String callNoStr = RequestPool.getSessionAttribute(Context.threadLocal_request_url).toString();
        if(body instanceof ResponseBody){
        	LoggerUtil.info(this.getClass(),userId+"["+callNoStr+ "]接口封装后返回数据：" + JsonUtil.beanToJson(body) + "\n---------------------------------\n");
        	return body;
        }
//        LoginInterceptor.useResponse.remove();
        ResponseBody responseBody = new ResponseBody();
        responseBody.setCode(200);
        responseBody.setData(body);
        // 处理空返回
        if (body == null) {
            //原本返回是否是集合
            if(Collection.class.isAssignableFrom(type)){
            	responseBody.setData(new ArrayList<>());
            	responseBody.setPage(new Page());
            }else{
            	responseBody.setData(new Object());
            }
        }
        // 处理集合返回
        else if (body instanceof Collection) {
			@SuppressWarnings("rawtypes")
			Collection list = (Collection) body;
            if (!list.isEmpty()) {
            	Object data = list.iterator().next();
                Page page = ObjectUtil.getAttributeValue(data, "page");
                responseBody.setPage(page);
            }else {
            	 responseBody.setPage(new Page());
            }
        }
        LoggerUtil.info(this.getClass(),userId+"["+callNoStr+ "]接口封装后返回数据：" + JsonUtil.beanToJson(responseBody) + "\n---------------------------------\n");
        //如果开启加解密，并且当前接口需要加密
        if(enableAuth && callNoStr.length() > 5){
        	String token = RequestPool.getToken();
        	String aesResult = StringUtil.AESEncode(JsonUtil.beanToJson(responseBody.getData()), token);
        	responseBody.setData(aesResult);
        	LoggerUtil.info(this.getClass(),userId+"["+callNoStr+ "]使用["+token+"]加密后返回数据：" + JsonUtil.beanToJson(responseBody) + "\n---------------------------------\n");
        }
        return responseBody;
    }
}